//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.ObjectModel;
using SR = Microsoft.Research.DataLayer;

namespace Microsoft.Research.ScientificWorkflow.TridentModel
{
    /// <summary>
    /// Contains information needed to create a job.
    /// </summary>
    public class JobDetailModel
    {
        /// <summary>
        /// The job id.
        /// </summary>
        private Guid jobId;

        /// <summary>
        /// The ID of the workflow which the job represents.
        /// </summary>
        private Guid workflowId;

        /// <summary>
        /// The ID of the node where the job will be executed.
        /// </summary>
        private Guid nodeId;

        /// <summary>
        /// The name of the job.
        /// </summary>
        private string jobName;

        /// <summary>
        /// The node name.
        /// </summary>
        private string nodeName;

        /// <summary>
        /// The name of the workflow which the job represents.
        /// </summary>
        private string workflowName;

        /// <summary>
        /// The description.
        /// </summary>
        private string description;

        /// <summary>
        /// The current job status.
        /// </summary>
        private SR.JobStatus status;

        /// <summary>
        /// The user on behalf of whom the job was created.
        /// </summary>
        private string scheduledBy;

        /// <summary>
        /// Additional parameters. For HPC.
        /// </summary>
        private Collection<AdditionalParametersModel> additionalParameters;

        /// <summary>
        /// Notes for the job.
        /// </summary>
        private string notes;
        
        /// <summary>
        /// Initializes the jobdetailmodel object.
        /// </summary>
        public JobDetailModel()
        {
            this.additionalParameters = new Collection<AdditionalParametersModel>();
            this.ParameterInfo = new WorkflowActivityParametersInfo();
        }

        /// <summary>
        /// Initializes the jobdetailmodel object.
        /// </summary>
        /// <param name="Job"></param>
        public JobDetailModel(SR.Job job)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }
            this.jobId = ((SR.IObject)job).ID;
            this.jobName = job.Name;
            this.scheduledBy = job.ScheduledBy.Name;

            if (job.Machines.Count > 0)
            {
                this.nodeName = job.Machines[0].Name;
            }

            SR.Activity workflow = job.ActivityInstances[0].Activity;
            this.workflowName = workflow.Name;
            this.workflowId = ((SR.IObject)workflow).ID;

            this.description = job.ErrorMessage;
            this.notes = job.Notes;

            this.additionalParameters = new Collection<AdditionalParametersModel>();
            this.status = job.Status;
            this.ReadAdditionalParameters(job);

            this.ParameterInfo = new WorkflowActivityParametersInfo();
            this.ReadWorkflowRequiredParametrs(job);

            this.IsTemplate = job.IsTemplate;
        }

        /// <summary>
        /// The job id.
        /// </summary>
        public Guid JobId
        {
            get
            {
                return jobId;
            }
        }

        /// <summary>
        /// The ID of the workflow which the job represents.
        /// </summary>
        public Guid WorkflowId
        {
            get
            {
                return workflowId;
            }
            set
            {
                workflowId = value;
            }
        }

        /// <summary>
        /// The ID of the node where the job will be executed.
        /// </summary>
        public Guid NodeId
        {
            get
            {
                return nodeId;
            }
            set
            {
                nodeId = value;
            }
        }

        /// <summary>
        /// The name of the job.
        /// </summary>
        public string JobName
        {
            get
            { 
                return jobName;
            }
            set
            { 
                jobName = value; 
            }
        }

        /// <summary>
        /// The node name.
        /// </summary>
        public string NodeName
        {
            get
            {
                return nodeName;
            }
        }

        /// <summary>
        /// The name of the workflow which the job represents.
        /// </summary>
        public string WorkflowName
        {
            get 
            {
                return workflowName; 
            }
            set
            { 
                workflowName = value; 
            }
        }

        /// <summary>
        /// The description.
        /// </summary>
        public string Description
        {
            get 
            {
                return description; 
            }
            set
            {
                description = value; 
            }
        }

        /// <summary>
        /// The current status of the workflow.
        /// </summary>
        public SR.JobStatus Status
        {
            get
            {
                return this.status;
            }
            set
            {
                this.status = value;
            }
        }


        /// <summary>
        /// The additional parameters. For HPC.
        /// </summary>
        public Collection<AdditionalParametersModel> AdditionalParameters
        {
            get
            {
                return this.additionalParameters;
            }
        }


        /// <summary>
        /// The user on behalf of whom the job was created.
        /// </summary>
        public string ScheduledBy
        {
            get
            {
                return scheduledBy;
            }
            set
            {
                scheduledBy = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string Notes
        {
            get
            {
                return this.notes;
            }
            set
            {
                this.notes = value;
            }
        }

        public bool IsDebug { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public bool IsTemplate { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public WorkflowActivityParametersInfo ParameterInfo { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="job"></param>
        private void ReadAdditionalParameters(SR.Job job)
        {
            foreach (SR.AdditionalParameter parameter in job.AdditionalParameters)
            {
                this.AdditionalParameters.Add(new AdditionalParametersModel(parameter));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="job"></param>
        private void ReadWorkflowRequiredParametrs(SR.Job job)
        {
            foreach (SR.ActivityInstanceParameter reqParameter in job.ActivityInstances[0].ActivityInstanceParameters)
            {
                this.ParameterInfo.Parameters.Add(new ActivityParameterInfo()
                {
                    ActivityUniqueName = reqParameter.ParameterAssignment.Instance.Name,
                    Name = reqParameter.ParameterAssignment.ActivityParameter.Name,
                    ActivityParameterInfoType = reqParameter.ParameterAssignment.ActivityParameter.Type,
                    Value = reqParameter.ParamValue
                });
            }
        }
    }
}
